/* 
 * File:   Thread.h
 * Author: maxds
 *
 * Created on 4 novembre 2011, 18:12
 */

#ifndef THREAD_H
#define	THREAD_H

#include <pthread.h>
#include <cstdlib>
#include <queue>


namespace Threading{

    typedef pthread_t           Thread;
    typedef pthread_cond_t      Vcondition;
    typedef pthread_mutex_t     Mutex;
    typedef pthread_attr_t      ThreadAttributs;
    typedef pthread_condattr_t  VconditionAttributs;
    typedef pthread_mutexattr_t MutexAttributs;
    

    /**
     * Cet item contient un pointeur sur les données
     * Et un pointeur sur le code qui va s'exécuter sur ces données
     */
    typedef struct {
        void* arg;
        void* fun;
    } work_item;


    /**
     * La file des travaux
     */
    std::queue<work_item> jobs;

    /**
     * 
     * @param fun
     * @param arg
     * @return
     */
    int add_job(void* fun ,void* arg){
        work_item* new_work = new work_item;
        new_work->arg = arg;
        new_work->fun = fun;
    }
    
    /**
     * Crée un thread simple sans propriétés d'ordonnancement
     * @param routine
     * @param args
     * @return
     */
    Thread* create_thread(void* (*routine) (void*), void* args){
        Thread* t = new Thread;
        int ret=pthread_create(t,NULL,routine,args);
        return (ret==0)?t:NULL;
    }

    /**
     *
     * @param t
     * @return
     */
    int join_thread(Thread* t){
        return pthread_join(*t,NULL);
    }


    /**
     * 
     * @param arg
     * @return
     */
    void* thread_work(void* arg){

        while(true){

            //Ici le code à executer
            std::printf("Hello from thread %d \n",(unsigned long int)pthread_self());

            //Ici piocher du travail dans la file du thread jusqu'elle soit vide
            //Les items contenus dans la file sont parametrés par les acteurs

            if(!jobs.empty()){
                work_item w= jobs.front();
                jobs.pop();
                //w.fun(w.arg);
            }
            
            //defiler un item de la file
            //item->start()
            
        }

    }
}

#endif	/* THREAD_H */

